Ovládněte React Error Boundaries pro vytváření odolných a uživatelsky přívětivých aplikací. Naučte se osvědčené postupy, techniky implementace a pokročilé strategie zpracování chyb.
React Error Boundaries: Techniky elegantního zpracování chyb pro robustní aplikace
V dynamickém světě webového vývoje je vytváření robustních a uživatelsky přívětivých aplikací nanejvýš důležité. React, populární JavaScriptová knihovna pro vytváření uživatelských rozhraní, poskytuje výkonný mechanismus pro elegantní zpracování chyb: Error Boundaries. Tato komplexní příručka se ponoří do konceptu Error Boundaries, zkoumá jejich účel, implementaci a osvědčené postupy pro vytváření odolných React aplikací.
Pochopení potřeby Error Boundaries
React komponenty, stejně jako jakýkoli kód, jsou náchylné k chybám. Tyto chyby mohou pramenit z různých zdrojů, včetně:
- Neočekávaná data: Komponenty mohou obdržet data v neočekávaném formátu, což vede k problémům s vykreslováním.
- Logické chyby: Chyby v logice komponenty mohou způsobit neočekávané chování a chyby.
- Externí závislosti: Problémy s externími knihovnami nebo API mohou šířit chyby do vašich komponent.
Bez řádného zpracování chyb může chyba v React komponentě zhroutit celou aplikaci, což má za následek špatnou uživatelskou zkušenost. Error Boundaries poskytují způsob, jak tyto chyby zachytit a zabránit jim v šíření po stromu komponent, a zajistit tak, že aplikace zůstane funkční i v případě selhání jednotlivých komponent.
Co jsou React Error Boundaries?
Error Boundaries jsou React komponenty, které zachycují JavaScriptové chyby kdekoli ve stromu podřízených komponent, zaznamenávají tyto chyby a zobrazují náhradní uživatelské rozhraní namísto stromu komponent, který se zhroutil. Fungují jako bezpečnostní síť, která zabraňuje zhroucení celé aplikace v důsledku chyb.
Klíčové charakteristiky Error Boundaries:
- Pouze třídní komponenty: Error Boundaries musí být implementovány jako třídní komponenty. Funkcionální komponenty a hooky nelze použít k vytvoření Error Boundaries.
- Životní cyklus metody: Používají specifické metody životního cyklu,
static getDerivedStateFromError()
acomponentDidCatch()
, ke zpracování chyb. - Lokální zpracování chyb: Error Boundaries zachycují pouze chyby ve svých podřízených komponentách, nikoli v sobě samotných.
Implementace Error Boundaries
Pojďme si projít proces vytváření základní Error Boundary komponenty:1. Vytvoření Error Boundary komponenty
Nejprve vytvořte novou třídní komponentu, například s názvem ErrorBoundary
:
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false
};
}
static getDerivedStateFromError(error) {
// Aktualizuje stav, takže další vykreslení zobrazí náhradní UI.
return {
hasError: true
};
}
componentDidCatch(error, errorInfo) {
// Můžete také zalogovat chybu do služby pro hlášení chyb
console.error("Chycená chyba: ", error, errorInfo);
// Příklad: logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// Můžete vykreslit libovolné vlastní náhradní UI
return (
<div>
<h2>Něco se pokazilo.</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}
<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundary;
Vysvětlení:
- Konstruktor: Inicializuje stav komponenty s
hasError: false
. static getDerivedStateFromError(error)
: Tato metoda životního cyklu je volána poté, co podřízená komponenta vyvolá chybu. Přijímá chybu jako argument a umožňuje vám aktualizovat stav komponenty. Zde nastavímehasError
natrue
, abychom spustili náhradní uživatelské rozhraní. Toto jestatic
metoda, takže uvnitř funkce nemůžete použítthis
.componentDidCatch(error, errorInfo)
: Tato metoda životního cyklu je volána poté, co podřízená komponenta vyvolala chybu. Přijímá dva argumenty:error
: Chyba, která byla vyvolána.errorInfo
: Objekt obsahující informace o zásobníku komponent, kde k chybě došlo. To je neocenitelné pro ladění.
V rámci této metody můžete zalogovat chybu do služby, jako je Sentry, Rollbar nebo vlastní řešení pro logování. Vyvarujte se pokusů o opětovné vykreslení nebo opravu chyby přímo v této funkci; jejím primárním účelem je zalogovat problém.
render()
: Metoda render kontroluje stavhasError
. Pokud jetrue
, vykreslí náhradní uživatelské rozhraní (v tomto případě jednoduchou chybovou zprávu). Jinak vykreslí podřízené prvky komponenty.
2. Použití Error Boundary
Chcete-li použít Error Boundary, jednoduše zabalte jakoukoli komponentu, která by mohla vyvolat chybu, do komponenty ErrorBoundary
:
import ErrorBoundary from './ErrorBoundary';
function MyComponent() {
// Tato komponenta může vyvolat chybu
return (
<ErrorBoundary>
<PotentiallyBreakingComponent />
</ErrorBoundary>
);
}
export default MyComponent;
Pokud PotentiallyBreakingComponent
vyvolá chybu, ErrorBoundary
ji zachytí, zaloguje chybu a vykreslí náhradní uživatelské rozhraní.
3. Ilustrativní příklady s globálním kontextem
Představte si aplikaci pro elektronické obchodování, která zobrazuje informace o produktech načtené ze vzdáleného serveru. Komponenta ProductDisplay
je zodpovědná za vykreslování podrobností o produktu. Server však může občas vrátit neočekávaná data, což vede k chybám vykreslování.
// ProductDisplay.js
import React from 'react';
function ProductDisplay({ product }) {
// Simulace potenciální chyby, pokud product.price není číslo
if (typeof product.price !== 'number') {
throw new Error('Neplatná cena produktu');
}
return (
<div>
<h2>{product.name}</h2>
<p>Cena: {product.price}</p>
<img src={product.imageUrl} alt={product.name} />
</div>
);
}
export default ProductDisplay;
Chcete-li se chránit před takovými chybami, zabalte komponentu ProductDisplay
do komponenty ErrorBoundary
:
// App.js
import React from 'react';
import ErrorBoundary from './ErrorBoundary';
import ProductDisplay from './ProductDisplay';
function App() {
const product = {
name: 'Example Product',
price: 'Not a Number', // Záměrně nesprávná data
imageUrl: 'https://example.com/image.jpg'
};
return (
<div>
<ErrorBoundary>
<ProductDisplay product={product} />
</ErrorBoundary>
</div>
);
}
export default App;
V tomto scénáři, protože product.price
je záměrně nastaveno na řetězec místo čísla, komponenta ProductDisplay
vyvolá chybu. Komponenta ErrorBoundary
tuto chybu zachytí, zabrání zhroucení celé aplikace a zobrazí náhradní uživatelské rozhraní namísto poškozené komponenty ProductDisplay
.
4. Error Boundaries v internacionalizovaných aplikacích
Při vytváření aplikací pro globální publikum by měly být chybové zprávy lokalizovány, aby poskytovaly lepší uživatelskou zkušenost. Error Boundaries lze použít ve spojení s knihovnami pro internacionalizaci (i18n) k zobrazení přeložených chybových zpráv.
// ErrorBoundary.js (s podporou i18n)
import React from 'react';
import { useTranslation } from 'react-i18next'; // Za předpokladu, že používáte react-i18next
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null,
};
}
static getDerivedStateFromError(error) {
return {
hasError: true,
error: error,
};
}
componentDidCatch(error, errorInfo) {
console.error("Chycená chyba: ", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
return (
<FallbackUI error={this.state.error} errorInfo={this.state.errorInfo}/>
);
}
return this.props.children;
}
}
const FallbackUI = ({error, errorInfo}) => {
const { t } = useTranslation();
return (
<div>
<h2>{t('error.title')}</h2>
<p>{t('error.message')}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{error && error.toString()}<br />
{errorInfo?.componentStack}
</details>
</div>
);
}
export default ErrorBoundary;
V tomto příkladu používáme react-i18next
k překladu názvu a zprávy chyby v náhradním uživatelském rozhraní. Funkce t('error.title')
a t('error.message')
načtou příslušné překlady na základě jazyka vybraného uživatelem.
5. Aspekty pro vykreslování na straně serveru (SSR)
Při používání Error Boundaries v aplikacích vykreslovaných na straně serveru je důležité správně zpracovávat chyby, aby se zabránilo zhroucení serveru. Dokumentace React doporučuje, abyste se vyhnuli používání Error Boundaries k obnovení z chyb vykreslování na serveru. Místo toho zpracovávejte chyby před vykreslením komponenty nebo vykreslete statickou chybovou stránku na serveru.Osvědčené postupy pro používání Error Boundaries
- Zabalte granulární komponenty: Zabalte jednotlivé komponenty nebo malé části vaší aplikace do Error Boundaries. Tím se zabrání zhroucení celého uživatelského rozhraní v důsledku jedné chyby. Zvažte zabalení konkrétních funkcí nebo modulů spíše než celé aplikace.
- Logujte chyby: Použijte metodu
componentDidCatch()
k logování chyb do monitorovací služby. To vám pomůže sledovat a opravovat problémy ve vaší aplikaci. Služby jako Sentry, Rollbar a Bugsnag jsou oblíbené pro sledování a hlášení chyb. - Poskytněte informativní náhradní uživatelské rozhraní: Zobrazte uživatelsky přívětivou chybovou zprávu v náhradním uživatelském rozhraní. Vyvarujte se technického žargonu a poskytněte pokyny, jak postupovat (např. obnovte stránku, kontaktujte podporu). Pokud je to možné, navrhněte alternativní akce, které může uživatel provést.
- Nepoužívejte příliš: Vyvarujte se zabalení každé jednotlivé komponenty do Error Boundary. Zaměřte se na oblasti, kde je pravděpodobnější výskyt chyb, jako jsou komponenty, které načítají data z externích rozhraní API nebo zpracovávají složité interakce uživatele.
- Testujte Error Boundaries: Zajistěte, aby vaše Error Boundaries fungovaly správně tím, že záměrně vyvoláte chyby v komponentách, které zabalují. Napište jednotkové testy nebo integrační testy, abyste ověřili, že se náhradní uživatelské rozhraní zobrazuje podle očekávání a že se chyby správně logují.
- Error Boundaries NEJSOU pro:
- Obsluhy událostí
- Asynchronní kód (např. zpětná volání
setTimeout
neborequestAnimationFrame
) - Vykreslování na straně serveru
- Chyby vyvolané v samotné Error Boundary (spíše než v jejích potomcích)
Pokročilé strategie zpracování chyb
1. Mechanismy opakování
V některých případech může být možné se z chyby zotavit opakováním operace, která ji způsobila. Pokud například selže síťový požadavek, můžete jej po krátké prodlevě zopakovat. Error Boundaries lze kombinovat s mechanismy opakování, aby poskytovaly odolnější uživatelskou zkušenost.
// ErrorBoundaryWithRetry.js
import React from 'react';
class ErrorBoundaryWithRetry extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
retryCount: 0,
};
}
static getDerivedStateFromError(error) {
return {
hasError: true,
};
}
componentDidCatch(error, errorInfo) {
console.error("Chycená chyba: ", error, errorInfo);
}
handleRetry = () => {
this.setState(prevState => ({
hasError: false,
retryCount: prevState.retryCount + 1,
}), () => {
// To vynutí opětovné vykreslení komponenty. Zvažte lepší vzory s řízenými props.
this.forceUpdate(); // VAROVÁNÍ: Používejte s opatrností
if (this.props.onRetry) {
this.props.onRetry();
}
});
};
render() {
if (this.state.hasError) {
return (
<div>
<h2>Něco se pokazilo.</h2>
<button onClick={this.handleRetry}>Zkusit znovu</button>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundaryWithRetry;
Komponenta ErrorBoundaryWithRetry
obsahuje tlačítko pro opakování, které po kliknutí resetuje stav hasError
a znovu vykreslí podřízené komponenty. Můžete také přidat retryCount
pro omezení počtu opakování. Tento přístup může být obzvláště užitečný pro zpracování přechodných chyb, jako jsou dočasné výpadky sítě. Ujistěte se, že je prop `onRetry` zpracován odpovídajícím způsobem a znovu načítá/vykonává logiku, která mohla způsobit chybu.
2. Příznaky funkcí
Příznaky funkcí vám umožňují dynamicky povolit nebo zakázat funkce ve vaší aplikaci bez nasazení nového kódu. Error Boundaries lze použít ve spojení s příznaky funkcí k elegantní degradaci funkčnosti v případě chyby. Pokud například konkrétní funkce způsobuje chyby, můžete ji zakázat pomocí příznaku funkce a zobrazit uživateli zprávu, že funkce je dočasně nedostupná.3. Vzor jističe
Vzor jističe je vzor návrhu softwaru používaný k zabránění aplikaci v opakovaných pokusech o provedení operace, která pravděpodobně selže. Funguje tak, že monitoruje míru úspěšnosti a selhání operace, a pokud míra selhání překročí určitou prahovou hodnotu, „otevře obvod“ a zabrání dalším pokusům o provedení operace na určitou dobu. To může pomoci zabránit kaskádovým selháním a zlepšit celkovou stabilitu aplikace.Error Boundaries lze použít k implementaci vzoru jističe v aplikacích React. Když Error Boundary zachytí chybu, může zvýšit čítač selhání. Pokud čítač selhání překročí prahovou hodnotu, může Error Boundary zobrazit uživateli zprávu, že funkce je dočasně nedostupná, a zabránit dalším pokusům o provedení operace. Po určité době může Error Boundary „uzavřít obvod“ a znovu povolit pokusy o provedení operace.
Závěr
React Error Boundaries jsou nezbytným nástrojem pro vytváření robustních a uživatelsky přívětivých aplikací. Implementací Error Boundaries můžete zabránit zhroucení celé aplikace v důsledku chyb, poskytnout uživatelům elegantní náhradní uživatelské rozhraní a logovat chyby do monitorovacích služeb pro ladění a analýzu. Dodržováním osvědčených postupů a pokročilých strategií uvedených v této příručce můžete vytvářet React aplikace, které jsou odolné, spolehlivé a poskytují pozitivní uživatelskou zkušenost, a to i tváří v tvář neočekávaným chybám. Nezapomeňte se zaměřit na poskytování užitečných chybových zpráv, které jsou lokalizovány pro globální publikum.